<!--
 * hi-avatar-group - 头像组
 *
 * @author 济南晨霜信息技术有限公司
 * @mobile 18560000860 / 18754137913
 -->
<template>
    <view class="hi-avatar-group" :class="_classes" :style="_styles">
        <view
            class="hi-avatar-group__item"
            v-for="(_item, _index) in avatars"
            :key="_index"
            :class="calcItemClass(_item, _index)"
            @animationend="onAnimationend(_index)"
            @tap="_emits('click', _item, _index)"
        >
            <image class="hi-avatar-group__image" :src="_item[keyName]" :mode="mode" />
        </view>
        <view class="hi-avatar-group__item hi-avatar-group__item--more" v-if="more" @tap="_emits('more')">
            <hi-icon class="hi-avatar-group__icon" :name="moreIcon"></hi-icon>
        </view>
    </view>
</template>

<!-- 由于 HbuilderX 不支持 defineOptions() 写法，故只能在此处进行配置 -->
<script>
    export default { options: uni?.$hi?.config?.componentsOptions || {} };
</script>

<script setup>
    import { ref, computed, onMounted, nextTick } from "vue";
    import props from "./props.js";

    // 组件属性
    const _props = defineProps(props);

    // 组件事件
    const _emits = defineEmits(["more", "click"]);

    // 组件类名
    const _classes = computed(() => {
        const classes = [];

        // 是否开启动画
        if (isAnimation.value) classes.push("hi-avatar-group--animation");

        // item 边框
        if (_props.itemBorder) classes.push("hi-avatar-group--item-border");

        // 更多按钮边框
        if (_props.moreBorder) classes.push("hi-avatar-group--more-border");

        return classes;
    });

    // 组件样式
    const _styles = computed(() => {
        const styles = [];

        // 头像大小
        if (_props.size) styles.push(`--hi-avatar-group-size: ${_props.size};`);

        // 头像偏移量
        if (_props.offset) styles.push(`--hi-avatar-group-offset: ${_props.offset};`);

        // item 边框颜色
        if (_props.itemBorderColor) styles.push(`--hi-avatar-group-item-border-color: ${_props.itemBorderColor};`);

        // item 圆角
        if (_props.itemRadius) styles.push(`--hi-avatar-group-item-border-radius: ${_props.itemRadius};`);

        // item 背景
        if (_props.itemBg) styles.push(`--hi-avatar-group-item-background: ${_props.itemBg};`);

        // 更多按钮边框颜色
        if (_props.moreBorderColor) styles.push(`--hi-avatar-group-more-border-color: ${_props.moreBorderColor};`);

        // 更多按钮圆角
        if (_props.moreRadius) styles.push(`--hi-avatar-group-more-border-radius: ${_props.moreRadius};`);

        // 更多按钮文字颜色
        if (_props.moreColor) styles.push(`--hi-avatar-group-more-color: ${_props.moreColor};`);

        // 更多按钮文字大小
        if (_props.moreFontSize) styles.push(`--hi-avatar-group-more-font-size: ${_props.moreFontSize};`);

        // 更多按钮背景
        if (_props.moreBg) styles.push(`--hi-avatar-group-more-background: ${_props.moreBg};`);

        return styles;
    });

    // 展示数据的起始索引
    const startIndex = ref(0);

    // 是否应用动画
    const isAnimation = computed(() => {
        // 头像数量小于设置的展示数量，不应用动画
        if (_props.list.length <= _props.count) return false;
        return _props.animation;
    });

    // 展示的头像列表
    const avatars = computed(() => {
        // 传入的头像列表长度 <= 设置的展示数量
        if (_props.list.length <= _props.count) return _props.list;

        // 开启了动画
        if (isAnimation.value) {
            // 多设置一个，用于动画
            const realCount = _props.count + 1;

            // 传入的头像列表长度 > 设置的展示数量
            // 如果从起始索引开始到结束的数量小于设置的展示数量
            if (_props.list.length - (startIndex.value + 1) < realCount) {
                // 剩余的头像列表
                const lastList = _props.list.slice(startIndex.value);
                // 循环从头像列表的起始索引开始到设置的展示数量
                return lastList.concat(_props.list.slice(0, realCount - lastList.length));
            }

            // 传入的头像列表长度 > 设置的展示数量
            return _props.list.slice(startIndex.value, startIndex.value + realCount);
        }

        // 没开启动画
        return _props.list.slice(0, _props.count);
    });

    // 动画状态
    const animationStatus = ref("wait");

    // 启动动画
    onMounted(() => {
        startAnimation();
    });

    /**
     * 计算 item 的 class
     */
    function calcItemClass(item, index) {
        const classes = [];

        // 第一个
        if (index === 0) classes.push("hi-avatar-group__item--first");

        // 最后一个
        if (index === avatars.value.length - 1) classes.push("hi-avatar-group__item--last");

        // 状态动画
        classes.push(`hi-avatar-group__item--animation-${animationStatus.value}`);

        return classes;
    }

    /**
     * 开始动画
     */
    function startAnimation() {
        if (isAnimation.value) {
            let timer = setTimeout(() => {
                animationStatus.value = "play";
                clearTimeout(timer);
            }, _props.delay);
        }
    }

    /**
     * 动画结束的回调函数
     * @param {count} index 头像下标，主要是为了只触发一次这个函数
     */
    function onAnimationend(index) {
        if (index !== 0) return;
        if (animationStatus.value === "play") {
            // 更新索引
            startIndex.value = startIndex.value + 1 >= _props.list.length ? 0 : startIndex.value + 1;

            nextTick(() => {
                let timer = setTimeout(() => {
                    animationStatus.value = "";
                    clearTimeout(timer);
                }, _props.time);
            });

            // 开始下次动画
            startAnimation();
        }
    }
</script>

<style lang="scss" scoped>
    .hi-avatar-group {
        display: var(--hi-avatar-group-display, inline-flex);
        align-items: var(--hi-avatar-group-align-items, center);

        &__item {
            width: var(--hi-avatar-group-size, 25px);
            height: var(--hi-avatar-group-size, 25px);
            border-radius: var(--hi-avatar-group-item-border-radius, 50%);
            overflow: var(--hi-avatar-group-item-overflow, hidden);
            position: var(--hi-avatar-group-item-position, relative);
            z-index: var(--hi-avatar-group-item-z-index, 1);
            flex-shrink: var(--hi-avatar-group-item-flex-shrink, 0);
            background: var(--hi-avatar-group-item-background, var(--hi-background-element));
            border: var(--hi-avatar-group-item-border-width, 0) var(--hi-avatar-group-item-border-style, solid)
                var(--hi-avatar-group-item-border-color, currentColor);
            animation-timing-function: var(--hi-avatar-group-item-animation-timing-function, linear);
            animation-duration: var(--hi-avatar-group-item-animation-duration, 500ms);
            animation-fill-mode: var(--hi-avatar-group-item-animation-fill-mode, forwards);
            margin-left: var(--hi-avatar-group-offset, -10px);

            &:first-child {
                margin-left: 0;
            }

            &--more {
                background: var(--hi-avatar-group-more-background, var(--hi-background-default));
                display: var(--hi-avatar-group-more-display, flex);
                align-items: var(--hi-avatar-group-more-align-items, center);
                justify-content: var(--hi-avatar-group-more-justify-content, center);
                border: var(--hi-avatar-group-more-border-width, 0) var(--hi-avatar-group-more-border-style, solid)
                    var(--hi-avatar-group-more-border-color, currentColor);
                border-radius: var(--hi-avatar-group-more-border-radius, 50%);
                font-size: var(--hi-avatar-group-more-font-size, inherit);
                color: var(--hi-avatar-group-more-color, inherit);
                margin-left: var(--hi-avatar-group-more-margin-left, var(--hi-avatar-group-offset, -10px));
            }
        }

        &__image {
            width: 100%;
            height: 100%;
            display: block;
        }

        &--animation {
            &.hi-avatar-group__item--animation-play {
                animation-name: hi-avatar-group-animate-move;
            }

            .hi-avatar-group__item--first {
                &.hi-avatar-group__item--animation-play {
                    animation-name: hi-avatar-group-animate-leave;
                }
            }

            .hi-avatar-group__item--last {
                opacity: 0;
                transform: scale(0);

                &.hi-avatar-group__item--animation-play {
                    animation-name: hi-avatar-group-animate-enter;
                }
            }

            .hi-avatar-group__item--more {
                margin-left: calc(-1 * var(--hi-avatar-group-size, 25px));
            }
        }

        @keyframes hi-avatar-group-animate-leave {
            100% {
                opacity: 0;
                transform: scale(0);
            }
        }

        @keyframes hi-avatar-group-animate-move {
            100% {
                transform: translateX(calc(-1 * (var(--hi-avatar-group-size, 25px) + var(--hi-avatar-group-offset, -10px))));
            }
        }

        @keyframes hi-avatar-group-animate-enter {
            100% {
                opacity: 1;
                transform: scale(1) translateX(calc(-1 * (var(--hi-avatar-group-size, 25px) + var(var--hi-avatar-group-offset, -10px))));
            }
        }
    }
</style>
